package com.opennews.openplatform

import grails.compiler.GrailsCompileStatic
import groovy.transform.TypeCheckingMode
import org.springframework.http.HttpStatus

@GrailsCompileStatic
class ProcessController extends BaseController {
    static allowedMethods = [
        deploy: "POST",
        deployAll: "POST"
    ]

    WorkflowProxy workflowProxy

    def index() {
        render("Hi ProcessController")
    }

    def getAllLatestActiveProcessDefinitions() {
        def result = workflowProxy.getAllLatestActiveProcessDefinitions()
        sendDataResponse(result)
    }

    def getLatestProcessDefinitionByKey() {
        def processDefinitionKey = params.processDefinitionKey.toString()
        def result = workflowProxy.getLatestProcessDefinitionByKey(processDefinitionKey)
        sendDataResponse(result)
    }

    def getProcessDefinitionByKey() {
        def processDefinitionKey = params.processDefinitionKey.toString()
        def result = workflowProxy.getProcessDefinitionByKey(processDefinitionKey)
        sendDataResponse(result)
    }

    def getAllLatestSuspendedProcessDefinitions() {
        def result = workflowProxy.getAllLatestSuspendedProcessDefinitions()
        sendDataResponse(result)
    }

    @GrailsCompileStatic(TypeCheckingMode.SKIP)
    def getProcessDefinitionModelByKey() {
        def processDefinitionKey = params.processDefinitionKey.toString()
        def result = workflowProxy.getProcessDefinitionModelByKey(processDefinitionKey)

        if (result != null) {
            response.contentType  = result.contentType
            response.outputStream << result.fileStream
            response.outputStream.flush()
        } else {
            render("Did NOT find the process definition with key: ${processDefinitionKey}")
        }
    }

    @GrailsCompileStatic(TypeCheckingMode.SKIP)
    def getProcessDefinitionModelByProcessDefinitionId() {
        def processDefinitionId = params.processDefinitionId.toString()
        def result = workflowProxy.getProcessModel(processDefinitionId)

        if (result != null) {
            response.contentType  = result.contentType
            response.outputStream << result.fileStream
            response.outputStream.flush()
        } else {
            render("Did NOT find the process definition with id: ${processDefinitionId}")
        }
    }

    def suspendProcessDefinitionByKey() {
        def processDefinitionKey = params.processDefinitionKey.toString()
        workflowProxy.suspendProcessDefinitionByKey(processDefinitionKey)

        render("Done")
    }

    def activateProcessDefinitionByKey() {
        def processDefinitionKey = params.processDefinitionKey.toString()
        workflowProxy.activateProcessDefinitionByKey(processDefinitionKey)

        render("Done")
    }

    def suspendProcessInstanceById() {
        def processInstanceId = params.processInstanceId.toString()
        workflowProxy.suspendProcessInstanceById(processInstanceId)

        render("Done")
    }

    def activateProcessInstanceById() {
        def processInstanceId = params.processInstanceId.toString()
        workflowProxy.activateProcessInstanceById(processInstanceId)

        render("Done")
    }

    def getProcessDefinition() {
        def processDefinitionId = params.processDefinitionId.toString()
        def result = workflowProxy.getProcessDefinitionById(processDefinitionId)

        sendDataResponse(result)
    }

    def queryProcessInstance() {
        def processDefinitionKey = params.processDefinitionKey.toString()
        def result = workflowProxy.queryProcessInstance(processDefinitionKey)

        sendDataResponse(result)
    }

    def getAllProcessInstances() {
        def result = workflowProxy.getAllProcessInstances()

        sendDataResponse(result)
    }

    def getProcessInstance() {
        def processInstanceId = params.processInstanceId.toString()
        def result = workflowProxy.getProcessInstance(processInstanceId)

        sendDataResponse(result)
    }

    def deleteProcessInstance() {
        def processInstanceId = params.processInstanceId.toString()
        def deleteReason = params.deleteReason.toString()
        workflowProxy.deleteProcessInstance(processInstanceId, deleteReason)

        render("Done")
    }

    def getActivityInstance() {
        def processInstanceId = params.processInstanceId.toString()
        def result = workflowProxy.getActivityInstance(processInstanceId)

        sendDataResponse(result)
    }

    @GrailsCompileStatic(TypeCheckingMode.SKIP)
    def startProcessInstanceByKey() {
        def processDefinitionKey = params.processDefinitionKey.toString()
        def result = workflowProxy.startProcessInstanceByKey(processDefinitionKey)

        sendDataResponse(result)
    }

    def getExecutionVariables() {
        def executionId = params.executionId.toString()
        def isLocal = params.boolean("isLocal")
        def result = workflowProxy.getExecutionVariables(executionId, isLocal)

        sendDataResponse(result)
    }

    def getTask() {
        def taskId = params.taskId.toString()
        def result = workflowProxy.getTask(taskId)
        sendDataResponse(result)
    }

    def getTaskByProcessInstanceAndAssignee() {
        def processInstanceId = params.processInstanceId.toString()
        def taskAssignee = params.taskAssignee.toString()
        def result = workflowProxy.getTaskByProcessInstanceAndAssignee(processInstanceId, taskAssignee)

        sendDataResponse(result)
    }

    def getTaskByProcessVariableValueEquals() {
        def variableName = params.variableName.toString()
        def variableValue = params.variableValue.toString()
        def result = workflowProxy.getTaskByProcessVariableValueEquals(variableName, variableValue)

        sendDataResponse(result)
    }

    def getTaskByAssignee() {
        def taskAssignee = params.taskAssignee.toString()
        def result = workflowProxy.getTaskByAssignee(taskAssignee)

        sendDataResponse(result)
    }

    def queryTask() {
        def processInstanceId = params.processInstanceId.toString()
        def result = workflowProxy.queryTask(processInstanceId)
        sendDataResponse(result)
    }

    @GrailsCompileStatic(TypeCheckingMode.SKIP)
    def completeTask() {
        def taskId = params.taskId.toString()
        workflowProxy.completeTask(taskId)

        render("Done")
    }

    def getStartFormVariables() {
        def processDefinitionId = params.processDefinitionId.toString()
        def result = workflowProxy.getStartFormVariables(processDefinitionId)

        sendDataResponse(result)
    }

    def getStartFormDataFormFields() {
        def processDefinitionId = params.processDefinitionId.toString()
        def result = workflowProxy.getStartFormDataFormFields(processDefinitionId)

        sendDataResponse(result)
    }

    def getTaskFormVariables() {
        def taskId = params.taskId.toString()
        def result = workflowProxy.getTaskFormVariables(taskId)

        sendDataResponse(result)
    }

    def getTaskComments() {
        def taskId = params.taskId.toString()
        def result = workflowProxy.getTaskComments(taskId)

        sendDataResponse(result)
    }

    def getTaskFormDataFormFields() {
        def taskId = params.taskId.toString()
        def result = workflowProxy.getTaskFormDataFormFields(taskId)

        sendDataResponse(result)
    }

    def historicProcessInstanceQuery() {
        def processDefinitionKey = params.processDefinitionKey.toString()
        def result = workflowProxy.historicProcessInstanceQuery(processDefinitionKey)

        sendDataResponse(result)
    }

    def historicProcessInstanceQueryByVariableValueEquals() {
        def variableName = params.variableName.toString()
        def variableValue = params.variableValue.toString()
        def result = workflowProxy.historicProcessInstanceQueryByVariableValueEquals(variableName, variableValue)

        sendDataResponse(result)
    }

    def getHistoricProcessInstance() {
        def processInstanceId = params.processInstanceId.toString()
        def result = workflowProxy.getHistoricProcessInstance(processInstanceId)

        sendDataResponse(result)
    }

    def deleteHistoricProcessInstance() {
        def processInstanceId = params.processInstanceId.toString()
        workflowProxy.deleteHistoricProcessInstance(processInstanceId)

        render("Done")
    }

    def migrationPlan() {
        def sourceProcessDefinitionId = "LoanRequestProcess:17:7220"
        def targetProcessDefinitionId = "LoanRequestProcess:18:7232"
        def mappedActivities = []

        mappedActivities << [
            sourceActivityId: "UserTask_VerifyCreditWorthiness",
            targetActivityId: "UserTask_VerifyCreditWorthiness"
        ]

        mappedActivities << [
            sourceActivityId: "Gateway_CheckRequestedAmount_New1",
            targetActivityId: "Gateway_CheckRequestedAmount_New2"
        ]

        workflowProxy.migrateAllProcessInstances(sourceProcessDefinitionId, targetProcessDefinitionId, mappedActivities)

        render("Done")
    }

    def deploy() {
        def filename = params.filename.toString()

        try {
            workflowProxy.deploy(filename)
        } catch (FileNotFoundException ex) {
            // render(status: HttpStatus.NOT_FOUND)
            respond(status: HttpStatus.NOT_FOUND)
        }

        sendStatusResponse(HttpStatus.NO_CONTENT)
    }

    def deployAll() {
        workflowProxy.deploy()
        sendStatusResponse(HttpStatus.NO_CONTENT)
    }
}
